package cn.ycq.im.commons.utils;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.*;

import java.util.Arrays;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;

public class GlobalPropertiesUtils implements EnvironmentPostProcessor {

    private static ConfigurableEnvironment environment;
    private static Map<String,Object> extraProperties;

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        GlobalPropertiesUtils.environment = environment;
        GlobalPropertiesUtils.extraProperties = new ConcurrentHashMap<>();

        MapPropertySource propertySource = new MapPropertySource("extra",this.extraProperties);
        environment.getPropertySources().addFirst(propertySource);
    }

    public static <T>T getProperty(String name,Class<T> targetType,T defaultValue){
        return environment.getProperty(name,targetType,defaultValue);
    }

    public static String getProperty(String name,String defaultValue){
        return environment.getProperty(name,defaultValue);
    }

    public static String getProperty(String name){
        return environment.getProperty(name,(String)null);
    }

    public static <T>T getProperty(String name,Class<T> targetType){
        return getProperty(name,targetType,null);
    }

    public static void setProperty(String propertyName,String propertyValue){
        extraProperties.put(propertyName,propertyValue);
    }

    public static String[] getPropertyNames(){
        SortedSet<String> result = new TreeSet<>();

        MutablePropertySources propertySources = environment.getPropertySources();
        for (PropertySource<?> propertySource : propertySources) {
            if (propertySource instanceof EnumerablePropertySource){
                String[] propertyNames = ((EnumerablePropertySource) propertySource).getPropertyNames();
                result.addAll(Arrays.asList(propertyNames));
            }
        }
        return result.toArray(new String[0]);
    }
}
